// chris 20 Dec 2011
package com.chrishobson.jreedemo.utils;

import static com.chrishobson.jreegl.gl.*;

/*
 * A base class of things that can be drawn, a Drawable issues OpenGL
 * commands when its Render method is called. The Render method must be
 * overriden by all derived objects, however Render is never directly
 * invoked, instead the Draw method is called by users which routes to
 * Render.
 * 
 */

abstract public class DlDrawable extends Drawable {
  
  public void Draw(Renderer a_Renderer) {
    if(m_ListId == 0) {
      m_ListId = glGenLists(1);
    }
    if(!m_ValidList) {
      glNewList(m_ListId, GL_COMPILE);
      Render(a_Renderer);
      glEndList();
      m_ValidList = true;
    }
    glCallList(m_ListId);
  }
  
  /**
   * Called when no longer required to allow the gl display list
   * to be released. The finalize will do this as well but
   * it cannot be sure that the correct OpenGL context is active.
   */
  public final void Destroy()
  {
    if(m_ListId != 0) {
      glDeleteLists(m_ListId,1);
      m_ListId = 0;
    }
  }
 
  /**
   * Derived classes call this when ever their data changes such
   * that they need to regenerate their display list. So the next time
   * Draw is called the display list is remade by calling the derived
   * classes Render method
   */
  protected void Modified()
  {
    m_ValidList = false;
  }
  
  public void finalize() {
    Destroy();
  }
  
  abstract public void Render(Renderer a_Renderer);
  
  private int m_ListId;
  private boolean m_ValidList;
}
